<?php

	/* The Desktop is essentially a set of switches which:
	
			* Interprets headers and $_GET data to determine the scenario
			* Where required instantiates an output buffer
			* Where required reads the first segment of an address and bootstraps the corresponding application
			* Sends domain and user info to javascript via a cookie
			* For sake of efficiency, short circuits further instantiation by sending simple javascript commands itself
	*/

	class Desktop{
		
		// Application
		var $APP;
	
		// Interpretation of address prefixes
		function readRequest(){
			// Absence of an arroba is interpreted as @desk/*
			if(substr(ARF, 0, 1) != '@') return array('fmgr', ARF);
			$req = explode('/', substr(ARF, 1));
			switch($req[0]){
				// @temp is excluded since it is not accessible via a GUI
				case 'docs':
				case 'desk':
				case 'home':
					return array('fmgr', ARF);
				default:
					return array(array_shift($req), implode('/', $req));
			}
		}
	
		// Application bootstrapper
		function APP(){
			if(is_null($this->APP)){
				list($pname, $rf) = $this->readRequest();
				switch($pname){
					case 'root':
						$dom = 'root';
						$pname = 'smroot';
						break;
					case 'smitten':
						$this->APP = Screen();
						return $this->APP;
					case 'smashjax':
						$this->APP = Smash();
						return $this->APP;
					default:
						 $dom = DOM_ID;
				}
				if(!$pkg = proxy($dom)->package($pname)) httpE(404, "No package $pname");
				$this->APP = $pkg->userInterface(array('rf'=>$rf));
			}
			return $this->APP;
		}
		
		// domain info for javascript
		function set_dom_cookie(){
			OB()->setcookie('DOM', new json(
				'id', DOM_ID,
				'name', Domain()->name
			), 0, '/', SERVER_NAME);
		}
		
		// user info for javascript
		function set_usr_cookie(){
			$d = new json(usr()->data());
			unset($d->user_agent);
			$d->set(
				'is_root', usr()->is_root(),
				'locality', DOM_ID,
				'last_login', sn()->session()->time_in
			);
			OB()->setcookie('USR', $d);
		}
		
		// die_smajax : shortcut to send javascript straight to the client and exit
		function die_smajax($cmd=''){
			//error_log($cmd);
			smout()->clean();
			if($cmd == 'ping') error_log('ping!');
			else smout()->jsln($cmd);
			smout()->flush();
			exit;
		}
			
####	The switches

		// run is called by Domain()->run()
		function run(){
			
			if(!ob_get_level()) ob_start();
			
			// Ajax is requested by setting "smajax" in the request header
			define('DOAJAX', req('smajax'));
			
			if(DOAJAX) smout()->set_handle('DskSmajax');
			// Upload is requested by sending authorisation token in query string
			define('DOUPLOAD', get('upload'));
			
			// Scenario switch:
			switch(true){
				
				// Honor apache's errors first
				case (isset($_GET['_e'])):
					trigger_error($_GET['_e']." (sent by apache)", E_USER_ERROR);
					exit;
					
				// These in turn call Desktop()->login_done() below
				case (isset($_GET['login'])):
				case (isset($_POST['login'])):
					sn()->open_session(post('name'), post('passwd')) ? $this->logged_in() : $this->logged_out();
					exit;
					
				// Visit to /?logout
				case (isset($_GET['logout'])):
					// Smernel wilil in turn call Desktop()->log_out() as defined below
					sn()->close_session();
					$this->logged_out();
					exit;
					
				// Upload script
				case (DOUPLOAD):
					// This script runs after upload has completed, so authorisation is done with pubkey
					// Set pubkey in $_GET array for benefit of smernel
					$_COOKIE['pubkey'] = array_shift(explode('/', DOUPLOAD));
					if(!sn()->restore_session()) $this->logged_out();
					getObj('Upload')->run();
					exit;
					
				case (DOAJAX):
					if(!sn()->restore_session()) $this->logged_out();
					if(post('ping')) $this->die_smajax('ping');
					if(post('getsalt')) $this->die_smajax("setsalt('".sn()->mkSalt(255)."');");
					$this->APP()->run();
					exit;
				
				default:
					if(!sn()->restore_session()) $this->logged_out();
					$this->set_dom_cookie();
					$this->set_usr_cookie();
					$this->APP()->run();
					exit;
			}
		}
		
		// Having logged a user in, Smernel calls this switch
		function logged_in(){
			switch(true){
				// User posted login data. never really happens except from unsupported clients
				 case (!DOAJAX):
					header("Location: /".ARF);
					exit;
					
				// User logged in from login screen
				case (post('hold')):
					$this->die_smajax("Login.done();");
				
				// User logged in using TUX or Smitten
				default:
					$this->set_usr_cookie();
					$this->die_smajax("Smernel.loadusr();");
			}
		}
		
		// Logout switch, called by Smernel
		function logged_out(){
			switch(true){
				// visit to /?logout
				case (isset($_GET['logout'])):
					header("Location: /");
					exit;
					
				// bad upload attempts
				case (DOUPLOAD):
					error_log("bad upload login attempt: {$_GET['pubkey']} from ".$_SERVER['REMOTE_ADDR']);
					exit;
					
				// ajax commands to closed session
				case (DOAJAX):
					$this->die_smajax("setsalt('".sn()->mkSalt()."'); Smajax.loggedout = 1; reauthenticate();");
					exit;
				
				// else login screen, from any address
				default:
					Screen()->run_login();
					exit;
			}
		}	
	}


